package com.ruoyi.business.service;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.business.*;
import com.ruoyi.business.ao.PublishGoodsEditAO;
import com.ruoyi.business.bo.PublishGoodsBuyByAdminBO;
import com.ruoyi.business.bo.PublishGoodsBuyByUserBO;
import com.ruoyi.business.enums.VipEnum;
import com.ruoyi.business.mapper.BuyMapper;
import com.ruoyi.business.mapper.PublishGoodsMapper;
import com.ruoyi.business.qo.BuyListQO;
import com.ruoyi.business.qo.PublishGoodsQO;
import com.ruoyi.business.vo.BuyVO;
import com.ruoyi.business.vo.PublishGoodsListVO;
import com.ruoyi.business.vo.PublishGoodsSttaticticsVO;
import com.ruoyi.business.vo.PublishGoodsVO;
import com.ruoyi.common.common.CommonEnum;
import com.ruoyi.common.common.ResultBody;
import com.ruoyi.common.exception.BizException;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @author ：jiangguanjun
 * @description：网站浏览记录
 * @date ：2020/7/16 21:13
 */
@Slf4j
@Component
public class PublishGoodsService {

    @Autowired
    private PublishGoodsMapper publishGoodsMapper;
    @Autowired
    private BuyMapper buyMapper ;
    @Autowired
    private UserService userService ;

    @Autowired
    private UserCategoryService userCategoryService ;

    @Value("${weixin.template.publishGoods.templateId}")
    private String templateId  ;
    @Value("${weixin.template.publishGoods.skip_url}")
    private String skipUrl  ;
    @Value("${weixin.template.publishGoods.title}")
    private String title  ;

    @Value("${weixin.template.publishGoods.remark}")
    private String remark  ;

    @Autowired
    private PushMessageService pushMessageService ;

    public int save(PublishGoods publishGoods) {
        return publishGoodsMapper.insertSelective(publishGoods) ;
    }

    /**
     * @author jiangguanjun
     * @date 2023/2/3 17:21
     * @param
     * @return
     * @desc 获取列表
     */
    public ResultBody list(PublishGoodsQO publishGoodsQO) {
        MyPage myPage = PageConfig.getPage();
        log.info("myPage:::{}",myPage);

        Page<PublishGoodsListVO> page = new Page<>(myPage.getPageNum(), myPage.getPageSize());
        PublishGoodsBO publishGoodsBO = new PublishGoodsBO() ;
        BeanUtils.copyProperties(publishGoodsQO,publishGoodsBO);
        if(publishGoodsBO.getCreateStartTime() != null){
            publishGoodsBO.setCreateStartDate(new Date(publishGoodsBO.getCreateStartTime()));
        }
        if(publishGoodsBO.getCreateEndTime() != null){
            publishGoodsBO.setCreateEndDate(new Date(publishGoodsBO.getCreateEndTime()));
        }
        if(publishGoodsBO.getPushEndTime() != null){
            publishGoodsBO.setPushEndDate(new Date(publishGoodsBO.getPushEndTime()));
        }
        if(publishGoodsBO.getPushStartTime() != null){
            publishGoodsBO.setPushStartDate(new Date(publishGoodsBO.getPushStartTime()));
        }

        IPage<PublishGoodsListVO> publishGoodsListVOIPage = publishGoodsMapper.queryPage(page,publishGoodsBO) ;
        publishGoodsListVOIPage.getRecords().forEach(publishGoodsListVO -> {
            log.info("publishGoodsListVO::::::{}", JSON.toJSONString(publishGoodsListVO));
        });
        return ResultBody.success(publishGoodsListVOIPage) ;
    }

    /**
     * @author jiangguanjun
     * @date 2023/2/3 17:21
     * @param
     * @return
     * @desc 变更状态
     */
    public int changeStatus(Integer status, Integer id) {
        PublishGoods publishGoods = new PublishGoods() ;
        publishGoods.setStatus(status);
        publishGoods.setId(id);
        return publishGoodsMapper.updateByPrimaryKeySelective(publishGoods) ;
    }

    public ResultBody edit(PublishGoodsEditAO publishGoodsEditAO) {


        PublishGoods publishGoods1 = new PublishGoods() ;
        BeanUtils.copyProperties(publishGoodsEditAO,publishGoods1);
        int res = publishGoodsMapper.updateByPrimaryKeySelective(publishGoods1) ;
        if(res>=0){
            return ResultBody.success() ;
        }
        return ResultBody.error(CommonEnum.PUBLISH_EDIT_ERROR) ;
    }

    public PublishGoods findById(Integer id) {
        return publishGoodsMapper.selectByPrimaryKey(id) ;
    }

    @Transactional
    public ResultBody buyByAdmin(PublishGoodsBuyByAdminBO publishGoodsBuyByAdminBO) {
        PublishGoods publishGoods = new PublishGoods() ;
        BeanUtils.copyProperties(publishGoodsBuyByAdminBO,publishGoods);
        int res = publishGoodsMapper.updateByPrimaryKeySelective(publishGoods) ;
        if(res<0){
            throw new BizException(CommonEnum.PUBLISH_BUY_ERROR) ;
        }

        // 更新购买表
        Buy buy = new Buy() ;
        buy.setbNum(publishGoodsBuyByAdminBO.getBuyNums());
        buy.setAdminBuy(1);
        buy.setpId(publishGoodsBuyByAdminBO.getId());
        res= buyMapper.insert(buy) ;
        if(res<0){
            throw new BizException(CommonEnum.PUBLISH_BUY_ERROR) ;
        }

        return ResultBody.success() ;
    }

    public ResultBody staticticsList(Integer cId, Integer adminId, Long createStartTime, Long createEndTime) {
        boolean excludeAdminBuy = true;
        Date startDate = null ;
        Date endDate = null ;
        if(createStartTime != null){
            startDate = new Date(createStartTime) ;
        }
        if(createEndTime != null){
            endDate = new Date(createEndTime) ;
        }
        List<PublishGoodsSttaticticsVO> publishGoodsSttaticticsVOSNoAdmin =  publishGoodsMapper.staticticsList(cId,adminId,startDate,endDate,excludeAdminBuy) ;
        excludeAdminBuy = false ;
        List<PublishGoodsSttaticticsVO> publishGoodsSttaticticsVOS =  publishGoodsMapper.staticticsList(cId,adminId,startDate,endDate,excludeAdminBuy) ;
        publishGoodsSttaticticsVOSNoAdmin.forEach(publishGoodsSttaticticsVO -> {
            publishGoodsSttaticticsVOS.forEach(publishGoodsSttaticticsVO1 -> {
                if(publishGoodsSttaticticsVO.getCId().equals(publishGoodsSttaticticsVO1.getCId())){
                    publishGoodsSttaticticsVO.setEffectiveCount(publishGoodsSttaticticsVO.getTotalCount());
                    publishGoodsSttaticticsVO.setTotalCount(publishGoodsSttaticticsVO1.getTotalCount());
                }
            });
        });
        log.info("publishGoodsSttaticticsVOS:::::{}",publishGoodsSttaticticsVOS);
        return ResultBody.success(publishGoodsSttaticticsVOSNoAdmin)  ;
    }

    /**
     * @author Administrator
     * @date 2023/2/16 14:45
     * @param
     * @return
     * @desc 推送采购信息给VIP客户
     */
    public ResultBody pushVip(Integer id, VipEnum vipEnum) {
        // 获取采购单基本信息
        PublishGoods publishGoods = publishGoodsMapper.selectByPrimaryKey(id) ;

        if(publishGoods == null){
            throw new BizException(CommonEnum.PUBLISH_NOT_EIXST_ERROR) ;
        }
        // 查找到相关VIP用户
        Integer cId = publishGoods.getcId() ;
        List<User> userList = userCategoryService.findByVipAndCid(vipEnum.getCode(),cId) ;

        // 如果用户不为空则编辑推送消息模板
        Date d = new Date() ;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
        String dateStr = format.format(d) ;
        JSONObject jsonObject = new JSONObject() ;
        JSONObject keyword1 = new JSONObject() ;
        keyword1.put("value",publishGoods.getName()) ;
        keyword1.put("color","#FF0000") ;
        jsonObject.put("keyword1",keyword1) ;
        JSONObject keyword2 = new JSONObject() ;
        keyword2.put("value",dateStr) ;
        jsonObject.put("keyword2",keyword2) ;
        JSONObject keyword3 = new JSONObject() ;
        keyword3.put("value",publishGoods.getProductName()) ;
        jsonObject.put("keyword3",keyword3) ;
        keyword3.put("color","#FF0000") ;
        JSONObject keyword4 = new JSONObject() ;
        keyword4.put("value",1) ;
        jsonObject.put("keyword4",keyword4) ;
        JSONObject first = new JSONObject() ;
        first.put("value",title) ;
        jsonObject.put("first",title) ;
        JSONObject remarkk = new JSONObject() ;
        remarkk.put("value",remark) ;
        jsonObject.put("remark",remarkk) ;


        // 发送推送消息给固定用户
        for (User user:userList) {
            String skip = String.format(skipUrl,id) ;
            log.info("跳转地址：：：{}",skip);
            Boolean b = pushMessageService.send(jsonObject,templateId,user.getOpenId(),skip) ;
            if(!b){
                log.warn("{},推送失败",user.getId());
            }
        }

        return ResultBody.success() ;
    }

    /**
     * 用户获取采购单详情，如果购买则显示手机号，如果没有购买则不显示手机号
     * @param id
     * @param userId
     * @return
     */
    public PublishGoodsVO findDetailByIdAndUserId(Integer id, Long userId) {

        PublishGoodsVO publishGoodsVO = publishGoodsMapper.selectVOById(id) ;
        if(publishGoodsVO == null){
            throw new BizException(CommonEnum.PUBLISH_NOT_EIXST_ERROR) ;
        }

        // 查询是否购买了该条采购单

        BuyListQO buyListQO = new BuyListQO() ;
        buyListQO.setpId(publishGoodsVO.getId());
        List<BuyVO> buys = buyMapper.selectListAll(buyListQO) ;
        List<Long > userIds = buys.stream().map(BuyVO::getuId).collect(Collectors.toList()) ;
        if(!userIds.contains(userId)){
            publishGoodsVO.setPhone(StringUtils.mask(publishGoodsVO.getPhone(),"*",3,5));
        }
        if(!CollectionUtils.isEmpty(buys)){
            return publishGoodsVO ;
        }
        publishGoodsVO.setBuyVOList(buys);

        return publishGoodsVO ;

    }

    /**
     * 用户获取采购单详情，如果购买则显示手机号，如果没有购买则不显示手机号
     * @param id
     * @return
     */
    public PublishGoodsVO findDetailById(Integer id) {

        PublishGoodsVO publishGoodsVO = publishGoodsMapper.selectVOById(id) ;
        if(publishGoodsVO == null){
            throw new BizException(CommonEnum.PUBLISH_NOT_EIXST_ERROR) ;
        }

        // 查询是否购买了该条采购单
        QueryWrapper queryWrapper = new QueryWrapper() ;
        queryWrapper.eq("p_id",publishGoodsVO.getId()) ;

        BuyListQO buyListQO = new BuyListQO() ;
        buyListQO.setpId(id);
        List<BuyVO> buys = buyMapper.selectListAll(buyListQO) ;


        if(StringUtils.isNotBlank(publishGoodsVO.getPhone())){
            publishGoodsVO.setPhone(StringUtils.mask(publishGoodsVO.getPhone(),"*",3,5));
        }

        publishGoodsVO.setBuyVOList(buys);


        return publishGoodsVO ;

    }

    @Transactional
    public ResultBody buyByUser(PublishGoodsBuyByUserBO publishGoodsBuyByUserBO) {
        PublishGoods publishGoods = new PublishGoods() ;
        BeanUtils.copyProperties(publishGoodsBuyByUserBO,publishGoods);
        int res = publishGoodsMapper.updateByPrimaryKeySelective(publishGoods) ;
        if(res<0){
            throw new BizException(CommonEnum.PUBLISH_BUY_ERROR) ;
        }

        // 校验余额，如果余额不足不能购买
        User user = userService.getById(publishGoodsBuyByUserBO.getUserId()) ;
        if(user == null ){
            throw new BizException(CommonEnum.USER_STATUS_ERROR) ;
        }
        Integer money = publishGoodsBuyByUserBO.getpPrice()*publishGoodsBuyByUserBO.getBuyNums() ;
        if(user.getBalance()-money<0){
            throw new BizException(CommonEnum.USER_BALANCE_EMPTY_ERROR) ;
        }

        // 更新购买表
        Buy buy = new Buy() ;
        buy.setbNum(publishGoodsBuyByUserBO.getBuyNums());
        buy.setuId(publishGoodsBuyByUserBO.getUserId());
        buy.setAdminBuy(0);
        buy.setpId(publishGoodsBuyByUserBO.getId());
        res= buyMapper.insert(buy) ;
        if(res<0){
            throw new BizException(CommonEnum.PUBLISH_BUY_ERROR) ;
        }

        return ResultBody.success() ;
    }

    public PublishGoodsVO getByStatusById(Integer id) {
        return publishGoodsMapper.selectVOById(id) ;
    }
}
